﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Net;
using System.IO;

namespace RedditViewer
{
    public class Post
    {
        public string Url { get; set; }
        public string PermaLink { get; set; }
        public string Title { get; set; }
        public int NumComments { get; set; }
        public string Subreddit { get; set; }
        public int Ups { get; set; }
        public int Downs { get; set; }
        public string Author { get; set; }
        public string Id { get; set; }
        public string Domain { get; set; }
        public string Error { get; set; }
        public string SavedTo { get; set; }
        public string After { get; set; }
        private bool Cancelling { get; set; }
        public int Score { get; set; }
        public double Created { get; set; }
        public Post()
        {
            Cancelling = false;
        }
        public void CancelLoad()
        {
            Cancelling = true;
        }
        public Uri Uri
        {
            get
            {
                return new Uri(this.Url);
            }
        }
        public DateTime CreateDate
        {
            get
            {
                var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                return epoch.AddSeconds(Created);
            }
        }
        public TimeSpan Age
        {
            get
            {
                return DateTime.UtcNow - CreateDate;
            }
        }
        public BitmapImage Image
        {
            get
            {
                if (imageData == null) return null;
                try
                {
                    BitmapImage image = new BitmapImage();
                    image.BeginInit();
                    image.StreamSource = new System.IO.MemoryStream(imageData);
                    image.EndInit();

                    return image;
                }
                catch (Exception ex)
                {
                    Error = ex.Message;
                    if (SavedTo != null)
                        File.Delete(SavedTo);
                    return null;
                }
            }
        }

        public bool IsObviousImage
        {
            get
            {
                return Url.EndsWith(".jpg") || Url.EndsWith(".png") || Url.EndsWith(".gif");
            }
        }
        public bool IsAlbum
        {
            get
            {
                return Domain.Contains("imgur") && Url.ToLower().Contains("/a/");
            }
        }
        public bool CanLoad
        {
            get
            {
                return !IsAlbum 
                    && !Url.EndsWith(".htm")
                    && !Url.EndsWith(".html")
                    && !Url.EndsWith("/") 
                    && !Url.Contains("flickr.com")
                    && !Url.ToLower().Contains(".gif");
            }
        }
        private byte[] imageData;

        public void Load(Action<double> percentLoaded, string saveToFolder)
        {
            if (imageData == null)
            {
                
                string url = Url;
                if (IsAlbum) return;
                if (
                    (Domain.Contains("imgur") || Domain.Contains("picsarus.com"))
                    && !IsObviousImage)
                {
                    url += ".jpg";
                }

                percentLoaded(0);

                try
                {

                    Uri u = new Uri(url);

                    string extension = Path.GetExtension(u.LocalPath);

                    string filename = this.Title;
                    foreach (char ch in Path.GetInvalidFileNameChars())
                        filename = filename.Replace("" + ch, "");

                    filename += extension;

                    string path = null;
                    if (saveToFolder != null)
                    {
                        path = Path.Combine(saveToFolder, Subreddit);
                        if (!Directory.Exists(path))
                            Directory.CreateDirectory(path);
                        path = Path.Combine(saveToFolder, Subreddit, filename);
                    }

                    if (File.Exists(path))
                    {
                        imageData = File.ReadAllBytes(path);
                        return;
                    }

                    if (Cancelling) return;


                    WebClient client = new WebClient();
                    client.DownloadProgressChanged += (sender, e) =>
                        {
                            percentLoaded((double)e.BytesReceived / e.TotalBytesToReceive);
                            if (Cancelling)
                                client.CancelAsync();
                        };
                    client.DownloadDataCompleted += (sender, e) =>
                        {
                            if (Cancelling || e.Error != null)
                                return;
                            imageData = e.Result;
                            if (path != null && imageData != null && imageData.Length > 0)
                            {
                                File.WriteAllBytes(path, imageData);
                                SavedTo = path;
                            }
                        };
                    client.DownloadDataAsync(u);
                    while (client.IsBusy)
                    {
                        System.Threading.Thread.Sleep(10);
                    }
                }
                catch(Exception ex)
                {
                    Error = ex.Message;
                }
            }
        }

    }
}
